package com.gzx.plugin.tjzy.modular.company.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONObject;
import com.aliyun.oss.ServiceException;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fhs.trans.service.impl.DictionaryTransService;
import com.gzx.plugin.tjzy.core.entity.CustomVo;
import com.gzx.plugin.tjzy.modular.caffeine.UserCaffeine;
import com.gzx.plugin.tjzy.modular.company.entity.GzxCompany;
import com.gzx.plugin.tjzy.modular.company.entity.bo.GzxCompanyAddOrEditBo;
import com.gzx.plugin.tjzy.modular.company.entity.bo.GzxCompanyIdBo;
import com.gzx.plugin.tjzy.modular.company.entity.bo.GzxCompanyQueryBo;
import com.gzx.plugin.tjzy.modular.company.entity.vo.GzxCompanyVo;
import com.gzx.plugin.tjzy.modular.company.mapper.GzxCompanyMapper;
import com.gzx.plugin.tjzy.modular.company.service.GzxCompanyListService;
import com.gzx.plugin.tjzy.modular.company.service.GzxCompanyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;
import vip.xiaonuo.common.consts.GzxDictConstant;
import vip.xiaonuo.common.consts.GzxTenantConstant;
import vip.xiaonuo.common.tenant.TenantContext;
import vip.xiaonuo.common.util.CommonCryptogramUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 委托公司Service业务层处理
 *
 * @author LionLi
 * @date 2024-09-10
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class GzxCompanyServiceImpl implements GzxCompanyService, InitializingBean {

    private final GzxCompanyMapper baseMapper;

    private final GzxCompanyListService companyListService;

    private final DictionaryTransService dictionaryTransService;

    private final UserCaffeine userCaffeine;

    /**
     * 分页查询委托公司列表
     *
     * @param companyQueryBo 查询条件
     * @return 委托公司分页列表
     */
    @Override
    @DS("tjzy")
    public Page<GzxCompanyVo> pageList(GzxCompanyQueryBo companyQueryBo) {
        LambdaQueryWrapper<GzxCompany> lqw = Wrappers.lambdaQuery();
        //公司编码
        lqw.eq(StringUtils.isNotBlank(companyQueryBo.getCompanyCode()), GzxCompany::getCompanyCode, companyQueryBo.getCompanyCode());
        //公司名称
        lqw.like(StringUtils.isNotBlank(companyQueryBo.getCompanyName()), GzxCompany::getCompanyName, companyQueryBo.getCompanyName());
        //税号/统一社会信用代码
        lqw.eq(StringUtils.isNotBlank(companyQueryBo.getUnifiedSocialCreditCode()), GzxCompany::getUnifiedSocialCreditCode, companyQueryBo.getUnifiedSocialCreditCode());
        //联系人姓名
        lqw.like(StringUtils.isNotBlank(companyQueryBo.getConcatName()), GzxCompany::getConcatName, companyQueryBo.getConcatName());
        //联系人电话
        if (StringUtils.isNotBlank(companyQueryBo.getConcatPhone())) {
            lqw.eq(GzxCompany::getConcatPhone, CommonCryptogramUtil.doSm1AesEncrypt(companyQueryBo.getConcatPhone()));
        }
        //银行卡号
        lqw.eq(StringUtils.isNotBlank(companyQueryBo.getBankAccount()), GzxCompany::getBankAccount, companyQueryBo.getBankAccount());
        //开户行
        lqw.eq(StringUtils.isNotBlank(companyQueryBo.getOpeningBank()), GzxCompany::getOpeningBank, companyQueryBo.getOpeningBank());
        lqw.orderByDesc(GzxCompany::getCreateTime);
        Map<String, JSONObject> aa = userCaffeine.getUserMapByTenantId(GzxTenantConstant.GZX_TENANT_ID);
        JSONObject userJson = aa.get("1543837863788879871");
        String positionLevel = userJson.getStr("positionLevel");
        if (StringUtils.isNotBlank(positionLevel) && "C1".equals(positionLevel)) {
            System.out.println(111);
        }
        return baseMapper.selectVoPage(new Page<>(companyQueryBo.getCurrent(), companyQueryBo.getSize()), lqw);
    }

    /**
     * 查询委托公司
     *
     * @param id 主键
     * @return 委托公司
     */
    @Override
    @DS("tjzy")
    public GzxCompanyVo queryById(Long id) {
        return BeanUtil.toBean(baseMapper.selectById(id), GzxCompanyVo.class);
    }

    /**
     * 查询所有公司
     *
     * @param val 公司名称
     * @return
     */
    @Override
    @DS("tjzy")
    public List<CustomVo> listAll(String val) {
        return convertList(baseMapper.selectList(Wrappers.<GzxCompany>lambdaQuery()
                .like(GzxCompany::getCompanyCode, val).or().like(GzxCompany::getCompanyName, val)));
    }

    /**
     * 新增委托公司
     *
     * @param companyAddOrEditBo 委托公司
     */
    @Override
    @DS("tjzy")
    public void insert(GzxCompanyAddOrEditBo companyAddOrEditBo) {
        //校验唯一公司编码是否存在
        verifyCompanyCode(companyAddOrEditBo.getCompanyCode(), null);
        GzxCompany company = BeanUtil.toBean(companyAddOrEditBo, GzxCompany.class);
        baseMapper.insert(company);
        refreshTransCache();
    }

    /**
     * 修改委托公司
     *
     * @param companyAddOrEditBo 委托公司
     */
    @Override
    @DS("tjzy")
    public void update(GzxCompanyAddOrEditBo companyAddOrEditBo) {
        //校验唯一公司编码是否存在
        verifyCompanyCode(companyAddOrEditBo.getCompanyCode(), companyAddOrEditBo.getId());
        GzxCompany company = BeanUtil.toBean(companyAddOrEditBo, GzxCompany.class);
        baseMapper.updateById(company);
        refreshTransCache();
    }

    /**
     * 校验并批量删除委托公司信息
     *
     * @param companyIdBo 待删除的主键集合
     * @return 是否删除成功
     */
    @Override
    @DS("tjzy")
    public void deleteWithValidByIds(GzxCompanyIdBo companyIdBo) {
        baseMapper.deleteBatchIds(companyIdBo.getCompanyIdList());
        refreshTransCache();
    }

    //校验唯一公司编码是否存在
    private void verifyCompanyCode(String companyCode, Long id) {
        LambdaQueryWrapper<GzxCompany> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(companyCode), GzxCompany::getCompanyCode, companyCode);
        lqw.ne(id != null, GzxCompany::getId, id);
        if (CollectionUtil.isNotEmpty(baseMapper.selectList(lqw))) {
            throw new ServiceException(companyCode + "：公司编码已存在");
        }
    }

    private List<CustomVo> convertList(List<GzxCompany> companyList) {
        List<CustomVo> customVoList = new ArrayList<>();
        for (GzxCompany company : companyList) {
            CustomVo customVo = new CustomVo();
            customVo.setId(company.getId());
            customVo.setValue(company.getCompanyCode());
            customVo.setLabel(company.getCompanyName());
            customVoList.add(customVo);
        }
        return customVoList;
    }

    @Override
    public void afterPropertiesSet() {
        refreshTransCache();
    }

    private void refreshTransCache() {
        CompletableFuture.supplyAsync(() -> {
            // 使用redis能解决共享问题，但是性能没有直接取缓存的好。
            dictionaryTransService.makeUseRedis();
            try {
                TenantContext.disableTenantFilter();
                List<GzxCompany> projectList = companyListService.getList();
                dictionaryTransService.refreshCache(GzxDictConstant.COMPANY, projectList.stream().collect(Collectors.toMap(GzxCompany::getCompanyCode, GzxCompany::getCompanyName)));
            } finally {
                TenantContext.enableTenantFilter();
                TenantContext.clear();
            }
            return null;
        }).exceptionally(ex -> {
            log.error("刷新公司缓存发生异常", ex);
            return null;
        });
    }
}
